Add support for HVM domains to new xm XenAPI create code
authorTom Wilkie <tom.wilkie@gmail.com>
Fri, 30 Mar 2007 16:28:54 +0000 (17:28 +0100)
committerTom Wilkie <tom.wilkie@gmail.com>
Fri, 30 Mar 2007 16:28:54 +0000 (17:28 +0100)
signed-off-by: Tom Wilkie <tom.wilkie@gmail.com>

tools/python/xen/xm/create.dtd
tools/python/xen/xm/xenapi_create.py

index 1c57a59d0602ac2cb682f061360656b0eb1879cc..b83050444aa1937734d4acdea97218591124e099 100644 (file)
@@ -37,6 +37,8 @@
                  memory,
                  vbd*,
                  vif*,
+                 console*,
+                 platform*,
                  vcpu_param*,
                  other_config*)> 
 <!ATTLIST vm     is_a_template          CDATA #REQUIRED
                  actions_after_shutdown %NORMAL_EXIT; #REQUIRED 
                  actions_after_reboot   %NORMAL_EXIT; #REQUIRED
                  actions_after_crash    %CRASH_BEHAVIOUR; #REQUIRED
-                 platform_std_VGA       CDATA #REQUIRED
-                 platform_serial        CDATA #REQUIRED
-                 platform_localtime     CDATA #REQUIRED 
-                 platform_clock_offet   CDATA #REQUIRED
-                 platform_enable_audio  CDATA #REQUIRED
                  PCI_bus                CDATA #REQUIRED> 
 
 <!ELEMENT memory EMPTY> 
@@ -76,6 +73,9 @@
                  qos_algorithm_type CDATA    #REQUIRED
                  network         CDATA       #IMPLIED> 
 
+<!ELEMENT console (other_config*)>
+<!ATTLIST console protocol       (vt100|rfb|rdp) #REQUIRED>
+
 <!ELEMENT pv     EMPTY>
 <!ATTLIST pv     kernel          CDATA #REQUIRED
                  bootloader      CDATA #REQUIRED
 <!ELEMENT label  (#PCDATA)> 
 <!ELEMENT description (#PCDATA)>
 
+<!ELEMENT platform   EMPTY>
+<!ATTLIST platform   key   CDATA #REQUIRED
+                     value CDATA #REQUIRED>
+
 <!ELEMENT vcpu_param EMPTY>
 <!ATTLIST vcpu_param key   CDATA #REQUIRED
                      value CDATA #REQUIRED>
index 31e59d831aa62515ed6415084c78bf38d96b7a2f..9e04e19970ffe2a4c86337b73d12975b5707aa22 100644 (file)
@@ -262,18 +262,8 @@ class xenapi_create:
                 vm.attributes["actions_after_reboot"].value,
             "actions_after_crash":
                 vm.attributes["actions_after_crash"].value,
-            "platform_std_VGA":
-                vm.attributes["platform_std_VGA"].value,
-            "platform_serial":
-                vm.attributes["platform_serial"].value,
-            "platform_localtime":
-                vm.attributes["platform_localtime"].value,
-            "platform_clock_offet":
-                vm.attributes["platform_clock_offet"].value,
-            "platform_enable_audio":
-                vm.attributes["platform_enable_audio"].value,
-            "PCI_bus":
-                vm.attributes["platform_enable_audio"].value,
+            "platform":
+                get_child_nodes_as_dict(vm, "platform", "key", "value"),
             "other_config":
                 get_child_nodes_as_dict(vm, "other_config", "key", "value")
             }
@@ -297,7 +287,7 @@ class xenapi_create:
                 "HVM_boot_policy":
                     get_child_node_attribute(vm, "hvm", "boot_policy"),
                 "HVM_boot_params":
-                    get_child_nodes_as_dict(hvm, "boot_params", "key", "value")
+                    get_child_nodes_as_dict(hvm, "boot_param", "key", "value")
                 })
         try:
             vm_ref = server.xenapi.VM.create(vm_record)
@@ -318,6 +308,12 @@ class xenapi_create:
 
             self.create_vifs(vm_ref, vifs)
 
+            # Now create consoles
+
+            consoles = vm.getElementsByTagName("console")
+
+            self.create_consoles(vm_ref, consoles)
+
             return vm_ref
         except:
             server.xenapi.VM.destroy(vm_ref)
@@ -401,6 +397,26 @@ class xenapi_create:
             self._network_refs = server.xenapi.network.get_all()
             return self._network_refs.pop(0)
 
+    def create_consoles(self, vm_ref, consoles):
+        log(DEBUG, "create_consoles")
+        return map(lambda console: self.create_console(vm_ref, console),
+                   consoles)
+
+    def create_console(self, vm_ref, console):
+        log(DEBUG, "create_consoles")
+
+        console_record = {
+            "VM":
+                vm_ref,
+            "protocol":
+                console.attributes["protocol"].value,
+            "other_params":
+                get_child_nodes_as_dict(console,
+                  "other_param", "key", "value")
+            }
+
+        return server.xenapi.console.create(console_record)
+
 def get_child_by_name(exp, childname, default = None):
     try:
         return [child for child in sxp.children(exp)
@@ -464,11 +480,6 @@ class sxp2xml:
             = actions_after_reboot
         vm.attributes["actions_after_crash"] \
             = actions_after_crash
-        vm.attributes["platform_std_VGA"] = "false"
-        vm.attributes["platform_serial"] = ""
-        vm.attributes["platform_localtime"] = ""
-        vm.attributes["platform_clock_offet"] = ""
-        vm.attributes["platform_enable_audio"] = ""
         vm.attributes["PCI_bus"] = ""
 
         vm.attributes["vcpus_max"] \
@@ -506,7 +517,13 @@ class sxp2xml:
             vm.appendChild(pv)
         elif image[0] == "hvm":
             hvm = document.createElement("hvm")
-            hvm.attributes["boot_policy"] = ""
+            hvm.attributes["boot_policy"] = "BIOS order"
+
+            boot_order = document.createElement("boot_param")
+            boot_order.attributes["key"] = "order"
+            boot_order.attributes["value"] \
+                = get_child_by_name(image, "boot", "abcd")
+            hvm.appendChild
 
             vm.appendChild(hvm)
 
@@ -540,6 +557,18 @@ class sxp2xml:
 
         map(vm.appendChild, vifs)
 
+        # Last but not least the consoles...
+
+        consoles = self.extract_consoles(image, document)
+
+        map(vm.appendChild, consoles)
+
+        # Platform variables...
+
+        platform = self.extract_platform(image, document)
+
+        map(vm.appendChild, platform)
+
         # transient?
 
         if transient:
@@ -637,6 +666,62 @@ class sxp2xml:
 
     _eths = -1
 
+    def mk_other_config(self, key, value, document):
+        other_config = document.createElement("other_config")
+        other_config.attributes["key"] = key
+        other_config.attributes["value"] = value
+        return other_config
+
+    def extract_consoles(self, image, document):
+        consoles = []
+
+        if int(get_child_by_name(image, "nographic", "1")) == 1:
+            return consoles
+        
+        if int(get_child_by_name(image, "vnc", "0")) == 1:
+            console = document.createElement("console")
+            console.attributes["protocol"] = "rfb"
+            console.appendChild(self.mk_other_config(
+                "vncunused", str(get_child_by_name(image, "vncunused", "0")),
+                document))
+            console.appendChild(self.mk_other_config(
+                "vnclisten",
+                get_child_by_name(image, "vnclisten", "127.0.0.1"),
+                document))
+            console.appendChild(self.mk_other_config(
+                "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
+                document))
+            consoles.append(console)          
+        if int(get_child_by_name(image, "sdl", "0")) == 1:
+            console = document.createElement("console")
+            console.attributes["protocol"] = "sdl"
+            console.appendChild(self.mk_other_config(
+                "display", get_child_by_name(image, "display", ""),
+                document))
+            console.appendChild(self.mk_other_config(
+                "xauthority",
+                get_child_by_name(image, "vxauthority", "127.0.0.1"),
+                document))
+            console.appendChild(self.mk_other_config(
+                "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
+                document))
+            consoles.append(console)
+            
+        return consoles
+
+
+    def extract_platform(self, image, document):
+        platform_keys = ['acpi', 'apic', 'pae']
+
+        def extract_platform_key(key):
+            platform = document.createElement("platform")
+            platform.attributes["key"] = key
+            platform.attributes["value"] \
+                = str(get_child_by_name(image, key, "1"))
+            return platform
+        
+        return map(extract_platform_key, platform_keys)
+    
     def getFreshEthDevice(self):
         self._eths += 1
         return "eth%i" % self._eths